LambdaでLine Notifyを使って予定通知をやってみた
こんにちはデータアナリティクス事業本部の下地です。
予定をlineに通知できないかなと調べると、Line Notifyを使うと出来そうですので実装してみたいと思います。
全体像
実装する全体像としては図のようになります。
流れとしては、以下のようになります。
- CloudWatchEventsで定時刻にLambdaを起動
- DynamoDBから予定取得、S3から画像取得
- lineに通知
前準備
作成前に以下の内容について準備します(DynamoDBには予定がすでに入っておりS3にも画像がある状態を想定し進めます)。
- Line Notifyトークン取得
- DynamoDBの予定確認
- ポリシー追加
- requestsをレイヤーに追加
- Lambda環境変数を設定
1. LINE Notifyトークン取得
こちらのサイト(LINE Notifyをnode.jsで利用する)を参考にLINE Notifyの登録を行いトークンを取得します。
- マイページより
トークンを発行
をクリックします。トークン名を記入し、1:1でLINE Notifyから通知を受け取るを選択します。 - トークンが発行されるので控えます。
2. DynamoDBの予定確認
DynamoDBには以下のデータが入っています。
3. ポリシー追加
LambdaからDynamoDBとS3へ接続するためAmazonS3FULLAccess
とAmazonDynamoDBFullAccess
の管理ポリシーを追加します。
4. requestsをレイヤーに追加
Lambdaでrequests
を使用するため、以下のリンクを参考にLambdaレイヤーに追加するための作業を行います。
- EC2にPython3.6.0の環境構築を行う
- EC2でrequestsをzip化する
- zipファイルをS3にupload
- Lambdaレイヤーに追加
Python3.6.0環境構築後に以下の手順でrequests
をzip化します。
$ mkdir requests $ pip install -t ./requests requests $ zip -r req.zip requests
EC2からexitし、下記scpコマンドを使用しrequests.zip
をダウンロードします。
$ scp -i ~/.ssh/***.pem ec2-user@**.***.*.*:/home/ec2-user/requests/requests.zip ./requests.zip
ローカルにダウンロードしたrequests.zip
をS3にアップロードします。そしてLambdaのレイヤーから選択し追加します。
5. Lambda環境変数を設定
Line Notifyのトークンなど必要な情報を、Lamdbaの環境変数に設定します。
実装
Line Notifyを使ってみる
まずは実行するとlineに通知するだけの機能を実装します。コードは以下のようになります。
lambdaに以下のコードを記入します。
import os import requests # Line Notify ACCESS_TOKEN = os.environ["access_token"] HEADERS = {"Authorization": "Bearer %s" % ACCESS_TOKEN} URL = "https://notify-api.line.me/api/notify" def lambda_handler(event, context): data = {'message': "send_test"} #lineに通知 requests.post(URL, headers=HEADERS, data=data)
では送信します。
lineに送信されたことが確認できました。
予定と画像を送信するコードを追加
次にDynamoDBから試験日の取得を行い、S3から画像を取得しlineに送信するために以下のようにコードを追加します。
import os import requests import boto3 from boto3.dynamodb.conditions import Key, Attr KEY_PICTURE= os.environ["key_picture"] DOWNLOAD_PATH = os.environ["download_path"] # Line Notify ACCESS_TOKEN = os.environ["access_token"] HEADERS = {"Authorization": "Bearer %s" % ACCESS_TOKEN} URL = "https://notify-api.line.me/api/notify" DYNAMO_DB = boto3.resource('dynamodb') DYNAMO_TABLE = DYNAMO_DB.Table(os.environ["table_name"]) S3_RESOURCE = boto3.resource("s3") BUCKET = S3_RESOURCE.Bucket(os.environ["bucket_name"]) def lambda_handler(event, context): #scanを使用して全件取得する。Dynamoからデータを取得し通知メッセージを作成 itemdata = DYNAMO_TABLE.scan(ConsistentRead=True) message = '日付:試験' for item in itemdata["Items"]: message += '\n' + item['date'] + '(' + item['day'] + "):" + item['exam'] print(message) data = {'message': message} # s3の画像を一時フォルダにアップロードし、画像ファイルを取得する BUCKET.download_file(KEY_PICTURE, DOWNLOAD_PATH) files = {'imageFile': open(DOWNLOAD_PATH, 'rb')} #予定と画像をlineに通知する requests.post(URL, headers=HEADERS, data=data, files=files)
CWEventsを設定
上記のコードを毎日12:00に通知するために、以下図のようにcron式と、作成したLambda名を設定しCWEventsを登録します。
結果
12:00に予定通知されました!
まとめ
Line Notifyを使用した通知が出来ました!DynamoDBのデータ取得やLambdaでrequestsを使う方法など少し回り道をしましたが通知ができるようになったので今後も使っていきたいと思います。ただ、今回作成した内容が試験日の通知ですので毎日気を引き締めて勉強しようと思いました。。最後まで読んでくれてありがとうございます。
参考URL
- PythonでLINEにメッセージを送る
- LINE Notifyをnode.jsで利用する
- AWS Lambda + LINE Notify で帰宅時に傘を忘れないようにLINEへ通知する
- DynamoDBで全件取得
- DynamoDBの基礎まとめ ― 読み込み(RCU)検証
- Python の HTTP クライアントは urllib.request で十分
- AWS Lambdaで Unable to import module エラーが発生したときは
- 【Python】AWS Lambdaで外部モジュールを使用する
- AWS CLIを使ってEC2のファイルをS3へアップロードしよう
- 【AWS Lambdaの基本コード その1】 S3からのファイル取得とローカル保存
- pandasをLambdaのLayerとして追加する
- Amazon Linux と Ubuntu に pyenv を入れて Python 3.6.0 の環境を作る方法
- EC2-ローカル間でのファイル転送